import { Component, OnInit, Input, ViewChild, ElementRef, AfterViewInit, Output, EventEmitter } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd';
import { register as registerFlow } from 'topology-flow-diagram';
// import { HttpService } from 'lbf';
import { Topology } from 'topology-core';
import { Line } from 'topology-core/models/line';
import { Node } from 'topology-core/models/node';
import { HttpClient } from '@angular/common/http';
import { HttpService } from 'lbf';
import { Subject, BehaviorSubject, Observer } from 'rxjs';
import { take, map, filter } from 'rxjs/operators';



@Component({
  selector: 'app-flow-steps',
  templateUrl: './flow-steps.component.html',
  styleUrls: ['./flow-steps.component.less']
})
export class FlowStepsComponent implements OnInit, AfterViewInit {



  @Input()
  delay = 0;

  @Input() spacing = 130

  @Input() width = 80
  @Input() height = 60
  @Input() stateColor_0 = "#EDEDED"
  @Input() stateColor_1 = "#87CEFA"
  @Input() stateColor_2 = "#C1FFC1"
  @Input() lineColor_0 = "#999999"
  @Input() lineColor_1 = "#1890ffff"
  @Input() lineColor_2 = "#52c41aff"

  @Input() borderRadius =0.1

  @Output() ok = new EventEmitter<string>();

  @Input()
  set stepsNodes(value) {
    this._stepsNodes = value

    this.stepsNodes$.next(value)
  }
  get stepsNodes() {
    return this._stepsNodes
  }
  _stepsNodes

  X_SPACELEN = 20

  stepsNodes$ = new BehaviorSubject<any>(null);
  start = {
    'id': 'start',
    'name': 'rectangle',
    'tags': [],
    'text': '开始',
    'rect': {
      'x': this.X_SPACELEN,
      'y': 225-(this.height/2),
      'width': this.width,
      'height': this.height,
      'center': { 'x': 404, 'y': 266 },
      'ex': 454,
      'ey': 316
    },
    'borderRadius':this.borderRadius

  }
  end = {
    'id': 'end',
    'name': 'rectangle',
    'tags': [],
    'text': '结束',
    'data':{
      'id': "end", 'text': "结束"
    },
    'rect': {
      'x': 150,
      'y': 210,
      'width': 80,
      'height': 30,
      'center': { 'x': 404, 'y': 266 },
      'ex': 454,
      'ey': 316
    },
    'paddingLeft': 10,
    'paddingRight': 10,
    'paddingTop': 5,
    'paddingBottom': 10,
    'borderRadius': 0.5,
  }
  data = {
    nodes: [],
    lines: []
  }
  canvas: Topology;
  canvasOptions = {
    on: (event: string, data: any) => { }
  }

  @ViewChild('view', { static: true }) view: ElementRef;
  constructor(
    public msgSrv: NzMessageService,
    private lbserver: HttpService,
    private http: HttpClient
  ) {
    registerFlow();
  }

  ngOnInit() {
    this.canvasOptions.on = this.onMessage

    this.stepsNodes$.pipe(
      filter(v=> {
          // console.log(v)
        return v != null}) // 判断是不是为空
    )
    .subscribe((res)=>{
      setTimeout(() => {
        this.showView()
    }, 500);
    })
  }

  ngAfterViewInit() {
    setTimeout(() => {
      this.canvas = new Topology(this.view.nativeElement, this.canvasOptions);
      this.canvas.open(this.data);

      this.canvas.render();
      this.canvas.resize()
      // this.showView()
      // console.log(this.canvas)
    }, this.delay
    )
  }


 

  mainInit() {

    let nodes = []
    let main = this.stepsNodes.main
    main.push(this.end)
    nodes = this.init(main, this.X_SPACELEN, 0);
    // 增加终点
    // console.log('nodes :', nodes);
    // if(nodes[nodes.length-1].id ==='end')
    // nodes.push(
    //   {
    //     ...this.end,
    //     rect: {
    //       ...this.end.rect,
    //       x: this.spacing * (main.length-1) + this.X_SPACELEN
    //     },
    //   }
    // )
    
    if(nodes[nodes.length-1].id ==='end')
       nodes[nodes.length-1] = this.nodePatchEnd(nodes[nodes.length-1])
    if(nodes[0].id ==='start')
    {
      nodes[0] = this.nodePatchStart(nodes[0])
    }

    // console.log(nodes)
    this.data = {
      nodes: [
        ...nodes
      ],
      lines: []
    }

  }

  branchInit() {
    let nodes = []
    let branch = this.stepsNodes.branch
    let main = this.stepsNodes.main
    let Yoffset = 0
    if(!branch && length === 0)
    return ;
    for (let index = 0; index < branch.length; index++) {
      const element = branch[index];
      let xindex
      for (let index = 0; index < main.length; index++) {
        const node = main[index];
        if (node.id === element.start) {
          xindex = index
          break;
        }
      }
      // console.log('xindex :', xindex[0]);
      let Xoffset = this.spacing * (xindex + 1)
      Yoffset = -Yoffset + this.spacing * ((index + 1) % 2)
      let data = element.nodes
      // 添加终点
      data.push({
        id: element.end
      })
      nodes = this.init(data, Xoffset + this.X_SPACELEN, Yoffset)
      this.data = {
        nodes: [
          ...this.data.nodes,
          ...nodes
        ],
        lines: [

        ]
      }
    }

  }

  /**
   * 
   * @param data 节点数组
   * @param Xoffset x轴偏移量
   * @param Yoffset y轴偏移量
   * @returns 返回节点
   */
  init(data, Xoffset, Yoffset) {
    // console.log('xoffset',Xoffset)
    // console.log('Yoffset',Yoffset);

    let nodes = []
    for (let index = 0; index < data.length-1 ; index++) {
      const node = data[index];
      nodes.push(
        {
          ...this.start,
          id: node.id,
          text: node.text,
          data: {
            to: data[index + 1].id,
            ...node
          },
          rect: {
            ...this.start.rect,
            x: this.spacing * index + Xoffset,
            y: this.start.rect.y + Yoffset
          },
          strokeStyle:(node.state === 0 ? this.lineColor_0 : node.state === 2 ? this.lineColor_2 : this.lineColor_1),
          fillStyle: (node.state === 0 ? this.stateColor_0 : node.state === 2 ? this.stateColor_2 : this.stateColor_1),//0 未完成 1 进行中 2 已完成
        }
      )
    }
    return nodes;
  }

  onMessage = (event: string, data: any) => {
    switch (event) {
      case 'node':
      case 'addNode':
        {
          // console.log(data)
          this.ok.emit(data.data)
        }
        break;
      case 'line':
      case 'addLine':

        break;
      case 'space':

        break;
      case 'moveOut':
      default:
        break;
    }
  }

  showView() {
    // console.log(this.canvas)
    this.mainInit();
    this.branchInit();
    this.canvas.open(this.data)
    this.canvas.render();
    this.draw()
    this.canvas.lock(1)
  }


  draw() {
    const nodes = this.canvas.data.pens
    for (let index = 0; index < nodes.length; index++) {
      const node = nodes[index];
      if (node.data) {
        for (let j = index; j < nodes.length; j++) {
          const item = nodes[j];
          if (node.data.to === item.id) {
            this.drawLine(node, item)
            break;
          }
        }
      }

    }
    this.drawBranch()
  }
  drawBranch() {
    const branch = this.stepsNodes.branch
    const nodes = this.canvas.data.pens
    // console.log('branch', branch)
    // tslint:disable-next-line: prefer-for-of
    if(!branch && length === 0)
      return ;
    for (let index = 0; index < branch.length; index++) {
      const element = branch[index];
      const len = element.nodes.length
      const branch_start_node = nodes.filter((node) => { if (node.id === element.start) return node })
      const branch_start_to_node = nodes.filter((node) => { if (node.id === element.nodes[0].id) return node })
      const branch_end_node = nodes.filter((node) => { if (node.id === element.end) return node })
      const branch_end_from_node = nodes.filter((node) => { if (node.id === element.nodes[len - 2].id) return node })
      //  console.log('element.nodes[len-1].id :', element.nodes[len-2].id);
      // console.log('branch_end_from_node:', branch_end_from_node);
      this.drawLine(branch_start_node[0], branch_start_to_node[0], 'polyline')
      this.drawLine(branch_end_from_node[0], branch_end_node[0], 'polyline')
    }
  }

  drawLine(from_node, to_node, line = "line") {
  }

  // todo 计算最长长度
  maxLenNode() {

  }
  
  // 改变初始
  nodePatchStart(node){
    let newNode = {
      ...node,
      rect:{
        ...node.rect,
        'width': 80,
        'height': 30,
        'y':210,
        'x': this.X_SPACELEN,
        'center': { 'x': 404, 'y': 266 },
        'ex': 454,
        'ey': 316
      },
      'fillStyle': null,
      'paddingLeft': 10,
      'paddingRight': 10,
      'paddingTop': 5,
      'paddingBottom': 10,
      'borderRadius': 0.5,
    }
    return newNode;
  }
  
    // 改变初始
    nodePatchEnd(node){
      let newNode = {
        ...node,
        rect:{
          ...node.rect,
          'width': 80,
          'height': 30,
           'y':210,
        },
        'data':{
          ...node.data,
          to:null,
        },
        'paddingLeft': 10,
        'paddingRight': 10,
        'paddingTop': 5,
        'paddingBottom': 10,
        'borderRadius': 0.5,
      }
      return newNode;
    }
}
